import 'package:backend.purchases/domain/entities/app_store_api/app_store_api_purchased_subscription_transaction.dart';
import 'package:backend.purchases/domain/entities/app_store_api/app_store_api_transaction_revocation_info.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_environment_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_offer_type_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_ownership_type_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_renewal_info_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_revocation_reason_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_transaction_dto.dart';

const kAppStoreApiSubscriptionTransactionExpirationTimeKey = 'expiresDate';

class AppStoreApiPurchasedSubscriptionTransactionDto extends AppStoreApiTransactionDto {
  const AppStoreApiPurchasedSubscriptionTransactionDto._internal({
    required this.id,
    required this.timeMs,
    required this.originalTransactionId,
    required this.purchaseItemSku,
    required this.offerTypeDto,
    required this.ownershipTypeDto,
    required this.environmentDto,
    required this.revocationTimeMs,
    required this.revocationReasonDto,
    required this.expirationTimeMs,
  });

  final String id;
  final int timeMs;
  final String originalTransactionId;
  final String purchaseItemSku;
  final AppStoreApiTransactionOfferTypeDto offerTypeDto;
  final AppStoreApiTransactionOwnershipTypeDto ownershipTypeDto;
  final int? revocationTimeMs;
  final AppStoreApiTransactionRevocationReasonDto? revocationReasonDto;
  final AppStoreApiEnvironmentDto environmentDto;
  final int expirationTimeMs;

  @override
  List<Object?> get props {
    return [
      id,
      timeMs,
      originalTransactionId,
      purchaseItemSku,
      offerTypeDto,
      ownershipTypeDto,
      revocationTimeMs,
      revocationReasonDto,
      environmentDto,
      expirationTimeMs,
    ];
  }

  factory AppStoreApiPurchasedSubscriptionTransactionDto.fromJson(Map<String, dynamic> json) {
    final offerTypeDto =
        AppStoreApiTransactionOfferTypeDto.fromCode(json[kAppStoreApiTransactionOfferTypeCodeKey]);

    final ownershipTypeDto = AppStoreApiTransactionOwnershipTypeDto.fromString(
        json[kAppStoreApiTransactionOwnershipTypeKey]);

    final environmentDto = AppStoreApiEnvironmentDto.fromString(
        json[kAppStoreApiPurchasedSubscriptionRenewalInfoEnvironmentKey]);

    final revocationReasonCode = json[kAppStoreApiTransactionRevocationReasonCodeKey] as int?;
    AppStoreApiTransactionRevocationReasonDto? revocationReasonDto;

    if (revocationReasonCode != null) {
      revocationReasonDto =
          AppStoreApiTransactionRevocationReasonDto.fromCode(revocationReasonCode);
    }

    return AppStoreApiPurchasedSubscriptionTransactionDto._internal(
      id: json[kAppStoreApiTransactionIdKey],
      timeMs: json[kAppStoreApiTransactionTimeKey],
      originalTransactionId: json[kAppStoreApiTransactionOriginalTransactionIdKey],
      purchaseItemSku: json[kAppStoreApiTransactionPurchaseItemSkuKey],
      offerTypeDto: offerTypeDto,
      ownershipTypeDto: ownershipTypeDto,
      revocationTimeMs: json[kAppStoreApiTransactionRevocationTimeKey],
      revocationReasonDto: revocationReasonDto,
      environmentDto: environmentDto,
      expirationTimeMs: json[kAppStoreApiSubscriptionTransactionExpirationTimeKey],
    );
  }

  @override
  AppStoreApiSubscriptionTransaction toEntity() {
    final time = DateTime.fromMillisecondsSinceEpoch(
      timeMs,
      isUtc: true,
    );

    DateTime? revocationTime;

    if (revocationTimeMs != null) {
      revocationTime = DateTime.fromMillisecondsSinceEpoch(
        revocationTimeMs!,
        isUtc: true,
      );
    }

    final expirationTime = DateTime.fromMillisecondsSinceEpoch(
      expirationTimeMs,
      isUtc: true,
    );

    AppStoreApiTransactionRevocationInfo? revocationInfo;

    if (revocationReasonDto != null) {
      revocationInfo = AppStoreApiTransactionRevocationInfo(
        time: revocationTime!,
        reason: revocationReasonDto!.toEntity(),
      );
    }

    return AppStoreApiSubscriptionTransaction(
      id: id,
      time: time,
      originalTransactionId: originalTransactionId,
      purchaseItemSku: purchaseItemSku,
      offerType: offerTypeDto.toEntity(),
      ownershipType: ownershipTypeDto.toEntity(),
      revocationInfo: revocationInfo,
      environment: environmentDto.toEntity(),
      expirationTime: expirationTime,
    );
  }
}
